system/popen: Avoid copying FILE#3511
Conversation
|
@nightt5879 it would be nice to have some test coverage to test it too. |
|
Thanks, I added a small The test opens two I verified the added test with:
The simulator run prints |
My bad, I looked only the first commit. So, everything is fine! |
Just to clarify: I added the additional commit after seeing your suggestion. |
23a698f to
9549d3b
Compare
|
@xiaoxiang781216 Thanks, I addressed the latest review comments in commit 6a16a4d. The follow-up changes:
One caveat I noticed while moving waitpid() into the fopencookie close callback: fclose() treats any non-OK close callback return as an EOF/error result. Because of that, popen_file_close() now returns OK after close() and waitpid() themselves succeed, and reports only close()/waitpid() failures as errors. Otherwise a normal nonzero shell termination status could be converted into an fclose() failure. I re-tested with:
|
|
@nightt5879 please rebase your patch to fix the conflict, thanks. |
Use fopencookie() to attach the popen fd and shell pid to the returned FILE stream instead of copying FILE into the popen container. Keep the upstream dpopen()/dpclose() implementation as the process and descriptor backend, and make pclose() close the cookie-backed stream directly. Fixes apache#2937. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>
433405a to
04ead82
Compare
|
@xiaoxiang781216 Rebased onto the latest master and force-pushed the branch. The conflict was resolved by keeping the upstream dpopen()/dpclose() implementation and the new testing/libc/popen test, then reapplying only the fopencookie() change in popen.c to avoid copying FILE. I re-tested with:
|
Thanks, the new version is much simple now. |
Summary
Fixes #2937.
system/popenwas embedding a copiedFILEobject in its private tracking container and copying it back inpclose(). That depends on libcFILElayout details.This PR makes
popen()return the actual stream fromfdopen()and keeps a small privateFILE * -> pidtracking list sopclose()can find the spawned shell process without copyingFILE.Scope:
popen()modes.pclose()responsible for closing the stream and waiting for the shell pid.EINVALifpclose()cannot find the stream in the private popen list.Impact
popen()/pclose()no longer rely on libcFILEinternals.Testing
Host:
sim:nshChecks:
git diff --check: passcheckpatch.sh -g HEAD~1..HEAD: passsim:nshbuild withCONFIG_SYSTEM_POPEN=yandCONFIG_EXAMPLES_POPEN=y: passCC: popen.cSIM elf with dynamic libs archive in nuttx.tgzprintf 'popen\npoweroff\n' | timeout 30s ./nuttx: passpopen("help")output is readpclose()